home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus Special 25 / AMIGAplus Sonderheft 25 (2000)(Falke)(DE)(Track 1 of 4)[!].iso / Updates / Hardware / FreeWheel / CxCustom.c < prev    next >
C/C++ Source or Header  |  2000-03-12  |  7KB  |  268 lines

  1.  
  2. #include <exec/types.h>
  3. #include <devices/inputevent.h>
  4. #include <libraries/commodities.h>
  5. #include <intuition/newmouse.h>
  6. #include <intuition/intuitionbase.h>
  7. #include <intuition/screens.h>
  8. #include <graphics/clip.h>
  9. #include <graphics/layers.h>
  10.  
  11. #include <clib/exec_protos.h>
  12. #include <clib/commodities_protos.h>
  13. #include <clib/alib_protos.h>
  14.  
  15. #include "WheelMouse.h"
  16. #include "Scroll.h"
  17. #include "Cx.h"
  18. #include "RawKey.h"
  19.  
  20. #include "CxCustom.h"
  21.  
  22. extern struct IntuitionBase *IntuitionBase;
  23. extern struct WheelMouseContext *MyWM;
  24. extern struct CxContext *Cx;
  25.  
  26. int AddIntAtomic(int *a,int v);
  27.  
  28. void HandleClickToFront(struct InputEvent *ie);
  29. void HandleClickScreenCycle(struct InputEvent *ie);
  30. BOOL InWindowBorder(struct Window *win);
  31.  
  32.  
  33. void CxDepthArrange(int dy)
  34. {
  35.   struct Window *win;
  36.   if(win=WindowUnderPointer())
  37.   {
  38.     if(win->Flags&WFLG_DEPTHGADGET)
  39.     {
  40.       if(dy<0)
  41.         WindowToBack(win);
  42.       else
  43.         WindowToFront(win);
  44.     }
  45.   }
  46. }
  47.  
  48.  
  49. void CxCustomRoutine(CxMsg *msg,CxObj *obj)
  50. {
  51.   static int xrem=0,yrem=0,lmb;
  52.   int x,y,dx,dy,msx,msy;
  53.   BOOL send=FALSE;
  54.   struct InputEvent *e=CxMsgData(msg);
  55.  
  56.   msx=MyWM->MouseSpeedX;
  57.   msy=MyWM->MouseSpeedY;
  58.  
  59.   dx=dy=0;
  60.  
  61.   if(((MyWM->ButtonState&1)&&(MyWM->MMBMode==ShiftClick))
  62.    ||((MyWM->ButtonState&2)&&(MyWM->FourthButtonMode==ShiftClick)))
  63.   {
  64.     e->ie_Qualifier&=~IEQUALIFIER_MIDBUTTON;
  65.     e->ie_Qualifier|=IEQUALIFIER_LEFTBUTTON|IEQUALIFIER_LSHIFT|IEQUALIFIER_RSHIFT;
  66.   }
  67.  
  68.   switch(e->ie_Class)
  69.   {
  70.     case IECLASS_RAWMOUSE:
  71.       x=e->ie_X; y=e->ie_Y;
  72.       if(msx>100)
  73.         if(x<3 && x>-3)
  74.           msx=100;
  75.       if(msy>100)
  76.         if(y<3 && y>-3)
  77.           msy=100;
  78.         x=e->ie_X*msx+xrem; xrem=x; x/=100; xrem-=x*100; e->ie_X=x;
  79.         y=e->ie_Y*msy+yrem; yrem=y; y/=100; yrem-=y*100; e->ie_Y=y;
  80.       switch(e->ie_Code)
  81.       {
  82.         case IECODE_MBUTTON:
  83.           HandleClickScreenCycle(e);
  84.           MyWM->ButtonState|=1;
  85.           switch(MyWM->MMBMode)
  86.           {
  87.             case Shift:
  88.             case ShiftDepth:
  89.               e->ie_Code=RK_LShift;
  90.               e->ie_Class=IECLASS_RAWKEY;
  91.               break;
  92.             case ShiftClick:
  93.               e->ie_Code=IECODE_LBUTTON;
  94.               e->ie_Qualifier=IEQUALIFIER_LSHIFT|IEQUALIFIER_RSHIFT;
  95.               break;
  96.             case CycleScreens:
  97.               if(MyWM->ButtonState&1)
  98.                 ScreenToBack(IntuitionBase->FirstScreen);
  99.               break;
  100.           }
  101.           break;
  102.         case IECODE_MBUTTON|IECODE_UP_PREFIX:
  103.           MyWM->ButtonState&=~1;
  104.           switch(MyWM->MMBMode)
  105.           {
  106.             case Shift:
  107.             case ShiftDepth:
  108.               e->ie_Class=IECLASS_RAWKEY;
  109.               e->ie_Code=RK_LShift|IECODE_UP_PREFIX;
  110.               break;
  111.             case ShiftClick:
  112.               e->ie_Code=IECODE_UP_PREFIX|IECODE_LBUTTON;
  113.               e->ie_Qualifier=IEQUALIFIER_LSHIFT|IEQUALIFIER_RSHIFT;
  114.               break;
  115.           }
  116.           break;
  117.         case IECODE_LBUTTON:
  118.           if(MyWM->ClickToFront||MyWM->ClickToBack)
  119.             HandleClickToFront(e);
  120.           break;
  121.       }
  122.     case IECLASS_RAWKEY:
  123.       switch(e->ie_Code)
  124.       {
  125.         case NM_BUTTON_FOURTH:
  126.           MyWM->ButtonState|=2;
  127.           switch(MyWM->FourthButtonMode)
  128.           {
  129.             case ShiftClick:
  130.               e->ie_Code=IECODE_LBUTTON;
  131.               e->ie_Qualifier=IEQUALIFIER_LSHIFT|IEQUALIFIER_RSHIFT;
  132.               break;
  133.             case CycleScreens:
  134.               if(MyWM->ButtonState&1)
  135.                 ScreenToBack(IntuitionBase->FirstScreen);
  136.               break;
  137.           }
  138.           break;
  139.         case NM_BUTTON_FOURTH|IECODE_UP_PREFIX:
  140.           if(MyWM->FourthButtonMode==ShiftClick)
  141.           {
  142.             e->ie_Code=IECODE_UP_PREFIX|IECODE_LBUTTON;
  143.             e->ie_Qualifier=IEQUALIFIER_LSHIFT|IEQUALIFIER_RSHIFT;
  144.           }
  145.           MyWM->ButtonState&=~2;
  146.           break;
  147.         case NM_WHEEL_UP:
  148.           dy=-1;
  149.           break;
  150.         case NM_WHEEL_DOWN:
  151.           dy=1;
  152.           break;
  153.         case NM_WHEEL_LEFT:
  154.           dx=-1;
  155.           break;
  156.         case NM_WHEEL_RIGHT:
  157.           dx=1;
  158.           break;
  159.       }
  160.  
  161.     if(dx||dy)
  162.     {
  163.       if(dy&&(MyWM->ButtonState&1)&&((MyWM->MMBMode==DepthArrange)||(MyWM->MMBMode==ShiftDepth)))
  164.       {
  165.         CxDepthArrange(dy);
  166.         MyWM->ButtonState&=~1;
  167.       }
  168.       else if(dy&&(MyWM->ButtonState&2)&&((MyWM->FourthButtonMode==DepthArrange)||(MyWM->FourthButtonMode==ShiftDepth)))
  169.       {
  170.         CxDepthArrange(dy);
  171.         MyWM->ButtonState&=~2;
  172.       }
  173.       else
  174.       {
  175.         /* As long as this addition is atomic, it is safe for the main
  176.            task to read the variables and this task to write them,
  177.            without semaphore protection.  The main task will read the
  178.            value, and then subtract the value it has just read (again
  179.            with an atomic operation). */
  180.         AddIntAtomic(&MyWM->ScrollY,dy);
  181.         AddIntAtomic(&MyWM->ScrollX,dx);
  182.         Signal(MyWM->MainTask,MyWM->Signals);
  183.       }
  184.     }
  185.     break;
  186.   }
  187.  
  188.   if(((MyWM->MMBMode==Shift)||(MyWM->MMBMode==ShiftDepth))&&(MyWM->ButtonState&1))
  189.   {
  190.     e->ie_Qualifier|=IEQUALIFIER_LSHIFT;
  191.     e->ie_Qualifier&=~IEQUALIFIER_MIDBUTTON;
  192.   }
  193.  
  194.   if(((MyWM->FourthButtonMode==Shift)||(MyWM->FourthButtonMode==ShiftDepth))&&(MyWM->ButtonState&2))
  195.     e->ie_Qualifier|=IEQUALIFIER_LSHIFT;
  196. }
  197.  
  198.  
  199. void HandleClickScreenCycle(struct InputEvent *ie)
  200. {
  201.   static long secs=0,microsecs=0,count=0;
  202.  
  203.   if((count==1) && (DoubleClick(secs,microsecs,ie->ie_TimeStamp.tv_secs,ie->ie_TimeStamp.tv_micro)))
  204.   {
  205.     ScreenToBack(IntuitionBase->FirstScreen);
  206.     count=0;
  207.   }
  208.   else
  209.   {
  210.     count=1;
  211.     secs=ie->ie_TimeStamp.tv_secs;
  212.     microsecs=ie->ie_TimeStamp.tv_micro;
  213.   }
  214. }
  215.  
  216.  
  217. void HandleClickToFront(struct InputEvent *ie)
  218. {
  219.   static struct Window *win=0,*lastwin=0;
  220.   static long secs=0,microsecs=0,count=0;
  221.  
  222.   win=WindowUnderPointer();
  223.   if(InWindowBorder(win))
  224.   {
  225.     if((count==1) && (win==lastwin) && (DoubleClick(secs,microsecs,ie->ie_TimeStamp.tv_secs,ie->ie_TimeStamp.tv_micro)))
  226.     {
  227.       struct Window *topwin=NULL;
  228.       if(win->WScreen->LayerInfo.top_layer)
  229.         topwin=win->WScreen->LayerInfo.top_layer->Window;
  230.       if((win==topwin)&&(MyWM->ClickToBack))
  231.         WindowToBack(win);
  232.       else
  233.         WindowToFront(win);
  234.       count=0;
  235.     }
  236.     else
  237.     {
  238.       count=1; lastwin=win;
  239.       secs=ie->ie_TimeStamp.tv_secs;
  240.       microsecs=ie->ie_TimeStamp.tv_micro;
  241.     }
  242.   }
  243. }
  244.  
  245.  
  246. BOOL InWindowBorder(struct Window *win)
  247. {
  248.   int x,y;
  249.   if(!win)
  250.     return(FALSE);
  251.   x=win->MouseX; y=win->MouseY;
  252.   if((win->Flags&WFLG_BORDERLESS)&&!(win->Flags&WFLG_BACKDROP))
  253.   {
  254.     if((x>0)&&(y>0)&&(x<win->Width)&&(y<win->Height))
  255.       return(TRUE);
  256.   }
  257.   if(x<win->BorderLeft)
  258.     return(TRUE);
  259.   if(y<win->BorderTop)
  260.     return(TRUE);
  261.   if(x>(win->Width-win->BorderRight-1))
  262.     return(TRUE);
  263.   if(y>(win->Height-win->BorderBottom-1))
  264.     return(TRUE);
  265.   return(FALSE);
  266. }
  267.  
  268.